package com.mi.cmdtest;


import android.os.SystemClock;

import com.magilit.framelibrary.utils.LogUtils;
import com.mi.cmdlibrary.magilit.bt.MagilitBT;

import java.io.UnsupportedEncodingException;

/**
 *
 * Created by lewis on 2018/3/14.
 */

public class UpdateHelper {

    private int updateprogress;
    private boolean wait;
    private int now_frame;  //眼罩升级进度表示
    private int frames;

    private MagilitBT bt;
    private byte[] data;
    private String fileName;

    public UpdateHelper(MagilitBT bt, byte[] data, String fileName) {
        this.bt = bt;
        this.data = data;
        this.fileName = fileName;
    }

    public boolean isWait() {
        return wait;
    }

    public void setWait(boolean wait) {
        this.wait = wait;
    }

    public void startFirmUpgrade() {

        new Thread(new Runnable() {

            @Override
            public void run() {


                do {
                    bt.getState().setRes(0);
                    byte[] frame_head = new byte[]{0x01, 0x00, (byte) 0xFF};
                    String pdata = fileName + " " + String.valueOf(data.length);
                    LogUtils.e("liusheng", "pdata:    " + pdata);

                    byte[] first_body = null;
                    try {
                        first_body = pdata.getBytes("ASCII");
                    } catch (UnsupportedEncodingException e1) {
                        e1.printStackTrace();
                    }
                    int paddinglen = pdata.length();
                    byte[] pad = new byte[128 - paddinglen];
                    byte[] body_data = new byte[128];
                    System.arraycopy(first_body, 0, body_data, 0, first_body.length);
                    System.arraycopy(pad, 0, body_data, first_body.length, pad.length);
                    int crc = Cal_CRC16(body_data, body_data.length);
                    byte[] crcb = new byte[]{(byte) (crc >> 8), (byte) (crc & 0xFF)};
                    byte[] packet = new byte[frame_head.length + 128 + 2];
                    System.arraycopy(frame_head, 0, packet, 0, frame_head.length);
                    System.arraycopy(body_data, 0, packet, frame_head.length, body_data.length);
                    System.arraycopy(crcb, 0, packet, frame_head.length + body_data.length, 2);
                    int i;

                    for (i = 0; i < packet.length / 20; i++) {
                        byte[] send_data = new byte[20];
                        System.arraycopy(packet, i * 20, send_data, 0, 20);
                        sendUpdateData(send_data);
                        waitSend();
                    }
                    byte[] send_data = new byte[13];
                    System.arraycopy(packet, i * 20, send_data, 0, 13);
                    sendUpdateData(send_data);

                    int sec = 0;
                    while (bt.getState().getRes() == 0 && bt.getState().isOnUpdating()) {
                        sec++;
                        SystemClock.sleep(100);
                        if (sec >= 100) {
                            LogUtils.e("liusheng", "失败1");
                            return;
                        }
                    }

                    if (bt.getState().getRes() == 0x1818) {
                        //CommonUtil.updating = false;
                        LogUtils.e("liusheng", "失败2");
                        return;
                    }
                    if (!bt.getState().isOnUpdating()) {
                        LogUtils.e("liusheng", "失败3");
                        return;
                    }
                } while (bt.getState().getRes() != 0x06);
                LogUtils.e("liusheng", "=====================================");
                frames = data.length / 128;
                now_frame = 0;
                int i = 0;
                while (now_frame < frames) {
                    //updateprogress++;
                    do {
                        if (bt.getState().getRes() == 0x15) {
                            LogUtils.e("liusheng",String.valueOf(now_frame + 1) + "已NAK，重发");
                        }
                        if (bt.getState().getRes() == 0x43) {
                            LogUtils.e("liusheng", String.valueOf(now_frame + 1) + "接收超时，重发");
                        }

                        if (bt.getState().getRes() == 0x06) {
                            LogUtils.e("liusheng", String.valueOf(now_frame) + "帧已ACK");
                        }
                        now_frame++;

                        byte[] packet = Getn_Packet(data, now_frame);
                        bt.getState().setRes(0);
                        i = 0;
                        for (i = 0; i < packet.length / 20; i++) {
                            byte[] send_data = new byte[20];
                            System.arraycopy(packet, i * 20, send_data, 0, 20);
                            sendUpdateData(send_data);
                            waitSend();
                        }
                        byte[] send_data = new byte[13];
                        System.arraycopy(packet, i * 20, send_data, 0, 13);
                        sendUpdateData(send_data);
                        LogUtils.e("liusheng", String.valueOf(now_frame) + "帧已发送");
                        int sec = 0;
                        while (bt.getState().getRes() == 0 && bt.getState().isOnUpdating()) {
                            sec++;
                            SystemClock.sleep(100);
                            if (sec >= 100) {
                                LogUtils.e("liusheng", "失败4");
                                return;
                            }
                        }


                        if (bt.getState().getRes() == 0x43) {
                            if (now_frame >= 1) {
                                now_frame = now_frame - 1;
                                LogUtils.e("liusheng", String.valueOf(now_frame + 1) + "帧接收超时");
                            } else {
                                LogUtils.e("liusheng", "失败5");
                                return;
                            }
                        }
                        if (bt.getState().getRes() == 0x15) {
                            if (now_frame >= 2) {
                                now_frame = now_frame - 2;
                                LogUtils.e("liusheng", String.valueOf(now_frame - 1) + "帧NAK");
                            } else {
                                LogUtils.e("liusheng", "失败6");
                                return;
                            }
                        }
                        if (bt.getState().getRes() == 0x1818) {
                            LogUtils.e("liusheng", "失败7");
                            return;
                        }
                        updateprogress = now_frame * 100 / frames;
                        LogUtils.e("liusheng", "进度： " + updateprogress);
                        //设置进度


                        if (!bt.getState().isOnUpdating()) {
                            LogUtils.e("liusheng", "失败8");
                            return;
                        }
                    } while (bt.getState().getRes() != 0x06);
                }

                LogUtils.e("liusheng","进度完成");
                bt.getState().setRes(0);
                do {
                    byte[] b = new byte[]{0x04};

                    sendUpdateData(b);
                    int sec = 0;
                    while (bt.getState().getRes() == 0 && bt.getState().isOnUpdating()) {
                        sec++;
                        SystemClock.sleep(100);
                        if (sec >= 100) {
                            LogUtils.e("liusheng", "失败9");

                            return;
                        }
                    }


                    if (!bt.getState().isOnUpdating()) {
                        LogUtils.e("liusheng", "失败10");
                        return;
                    }
                } while (bt.getState().getRes() != 0x06);

                do {
                    bt.getState().setRes(0);
                    byte[] frame_head = new byte[]{0x01, 0x00, (byte) 0xFF};
                    byte[] body_data = new byte[128];
                    int crc = Cal_CRC16(body_data, body_data.length);
                    byte[] crcb = new byte[]{(byte) (crc >> 8), (byte) (crc & 0xFF)};
                    byte[] packet = new byte[frame_head.length + 128 + 2];
                    System.arraycopy(frame_head, 0, packet, 0, frame_head.length);
                    System.arraycopy(body_data, 0, packet, frame_head.length, body_data.length);
                    System.arraycopy(crcb, 0, packet, frame_head.length + body_data.length, 2);
                    for (i = 0; i < packet.length / 20; i++) {
                        byte[] send_data = new byte[20];
                        System.arraycopy(packet, i * 20, send_data, 0, 20);
                        sendUpdateData(send_data);
                        waitSend();
                    }
                    byte[] send_data = new byte[13];
                    System.arraycopy(packet, i * 20, send_data, 0, 13);
                    sendUpdateData(send_data);
                    LogUtils.e("liusheng","传输结束符已发送");
                    int sec = 0;
                    while (bt.getState().getRes() == 0 && bt.getState().isOnUpdating()) {
                        sec++;
                        SystemClock.sleep(100);
                        if (sec >= 100) {
                            LogUtils.e("liusheng", "失败11");
                            //失败
                            return;
                        }
                    }

                    if (!bt.getState().isOnUpdating()) {
                        LogUtils.e("liusheng", "失败12");
                        //失败
                        return;
                    }
                } while (bt.getState().getRes() != 0x06);

                LogUtils.e("liusheng","传输结束");
//                BLEState.onUpdating = false;

                LogUtils.e("liusheng", "成功");
            }
        }).start();
    }

    private int Cal_CRC16(byte[] p_data, int size) {
        int crc = 0;

        for (int i = 0; i < size; i++) {
            crc = UpdateCRC16(crc, p_data[i] & 0x0FF);
        }

        crc = UpdateCRC16(crc, 0);
        crc = UpdateCRC16(crc, 0);

        return crc & 0xFFFF;
    }

    /**
     * CRC16计算相关函数
     *
     * @return CRC16
     */
    private int UpdateCRC16(int crc_in, int bt) {
        int crc = crc_in;
        int in = bt | 0x100;
        do {
            crc = crc << 1;
            in = in << 1;
            if ((in & 0x100) != 0) crc = crc + 1;
            if ((crc & 0x10000) != 0) crc = crc ^ 0x1021;

        } while ((in & 0x10000) == 0);
        return crc & 0xFFFF;
    }

    /**
     * 拆包函数
     */

    private byte[] Getn_Packet(final byte data[], final int num) {  //num>=1;
        byte[] frame_head = new byte[]{0x01, 0x00, (byte) 0xFF};
        frame_head[1] = (byte) (num & 0x0FF);
        frame_head[2] = (byte) (frame_head[1] ^ 0xFF);
        //String str= CommonUtil.backCMD2String(frame_head);
        //String[] cmds = str.split("-");
        //System.out.println("序号"+Arrays.asList(cmds));
        byte[] pdata = new byte[128];
        System.arraycopy(data, (num - 1) * 128, pdata, 0, 128);
        int crc1 = Cal_CRC16(pdata, pdata.length);
        byte[] crcb = new byte[]{(byte) (crc1 >> 8), (byte) (crc1 & 0x0FF)};
        byte[] packet = new byte[frame_head.length + 128 + 2];
        System.arraycopy(frame_head, 0, packet, 0, frame_head.length);
        System.arraycopy(pdata, 0, packet, frame_head.length, pdata.length);
        System.arraycopy(crcb, 0, packet, frame_head.length + pdata.length, 2);
        return packet;
    }


    private void waitSend() {
        wait = true;
        while (wait) {
            SystemClock.sleep(100);
        }
    }

    private void sendUpdateData(byte[] data) {
        bt.send(data);
    }

    private void sendStart() {
        bt.updateFirm();
    }
}
